#ifndef TFunction_h
#define TFunction_h

#include "TAlgorithm.h"
#include "TArg.h"
namespace Fun{

    template <class tFunc, 
    class tArg1=SEmpty, class tArg2=SEmpty, class tArg3=SEmpty,
    class tArg4=SEmpty, class tArg5=SEmpty, class tArg6=SEmpty,class tArg7=SEmpty>
    class TFunction
    {
    public:
        ~TFunction(){}
    public:
        TFunction(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3,tArg4 arg4,tArg5 arg5,tArg6 arg6,tArg7 arg7)
            :mFunc(func), mArg1(arg1), mArg2(arg2), mArg3(arg3), mArg4(arg4), mArg5(arg5), mArg6(arg6), mArg7(arg7)
        {}
    public:
        typename Servise::TFuncTraits<tFunc>::Return_t Execute()
        { return (*mFunc)(mArg1,mArg2,mArg3,mArg4,mArg5,mArg6,mArg7);}
    protected:
        tFunc mFunc; tArg1 mArg1;tArg2 mArg2;tArg3 mArg3;tArg4 mArg4;tArg5 mArg5;tArg6 mArg6;tArg7 mArg7;
    };

    template <class tFunc, class tArg1, class tArg2, class tArg3,class tArg4, class tArg5, class tArg6>
    class TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,tArg5,tArg6,SEmpty>
    {
    public:
        ~TFunction(){}
    public:
        TFunction(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3,tArg4 arg4,tArg5 arg5,tArg6 arg6)
            :mFunc(func), mArg1(arg1), mArg2(arg2), mArg3(arg3), mArg4(arg4), mArg5(arg5), mArg6(arg6)
        {}
    public:
        typename Servise::TFuncTraits<tFunc>::Return_t Execute()
        { return (*mFunc)(mArg1,mArg2,mArg3,mArg4,mArg5,mArg6);}
    protected:
        tFunc mFunc; tArg1 mArg1;tArg2 mArg2;tArg3 mArg3;tArg4 mArg4;tArg5 mArg5;tArg6 mArg6;
    };

    template <class tFunc, class tArg1, class tArg2, class tArg3,class tArg4, class tArg5>
    class TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,tArg5,SEmpty,SEmpty>
    {
    public:
        ~TFunction(){}
    public:
        TFunction(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3,tArg4 arg4,tArg5 arg5)
            :mFunc(func), mArg1(arg1), mArg2(arg2), mArg3(arg3), mArg4(arg4), mArg5(arg5)
        {}
    public:
        typename Servise::TFuncTraits<tFunc>::Return_t Execute()
        { return (*mFunc)(mArg1,mArg2,mArg3,mArg4,mArg5);}
    protected:
        tFunc mFunc; tArg1 mArg1;tArg2 mArg2;tArg3 mArg3;tArg4 mArg4;tArg5 mArg5;
    };

    template <class tFunc, class tArg1, class tArg2, class tArg3,class tArg4>
    class TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,SEmpty,SEmpty,SEmpty>
    {
    public:
        ~TFunction(){}
    public:
        TFunction(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3,tArg4 arg4)
            :mFunc(func), mArg1(arg1), mArg2(arg2), mArg3(arg3), mArg4(arg4)
        {}
    public:
        typename Servise::TFuncTraits<tFunc>::Return_t Execute()
        { return (*mFunc)(mArg1,mArg2,mArg3,mArg4);}
    protected:
        tFunc mFunc; tArg1 mArg1;tArg2 mArg2;tArg3 mArg3;tArg4 mArg4;
    };

    template <class tFunc, class tArg1, class tArg2, class tArg3>
    class TFunction<tFunc, tArg1,tArg2,tArg3,SEmpty,SEmpty,SEmpty,SEmpty>
    {
    public:
        ~TFunction(){}
    public:
        TFunction(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3)
            :mFunc(func), mArg1(arg1), mArg2(arg2), mArg3(arg3)
        {}
    public:
        typename Servise::TFuncTraits<tFunc>::Return_t Execute()
        { return (*mFunc)(mArg1,mArg2,mArg3);}
    protected:
        tFunc mFunc; tArg1 mArg1;tArg2 mArg2;tArg3 mArg3;
    };

    template <class tFunc, class tArg1, class tArg2>
    class TFunction<tFunc, tArg1,tArg2,SEmpty,SEmpty,SEmpty,SEmpty,SEmpty>
    {
    public:
        ~TFunction(){}
    public:
        TFunction(tFunc func, tArg1 arg1,tArg2 arg2)
            :mFunc(func), mArg1(arg1), mArg2(arg2)
        {}
    public:
        typename Servise::TFuncTraits<tFunc>::Return_t Execute()
        { return (*mFunc)(mArg1,mArg2);}
    protected:
        tFunc mFunc; tArg1 mArg1;tArg2 mArg2;
    };

    template <class tFunc, class tArg1>
    class TFunction<tFunc, tArg1,SEmpty,SEmpty,SEmpty,SEmpty,SEmpty,SEmpty>
    {
    public:
        ~TFunction(){}
    public:
        TFunction(tFunc func, tArg1 arg1):mFunc(func), mArg1(arg1){}
    public:
        typename Servise::TFuncTraits<tFunc>::Return_t Execute()
        { return (*mFunc)(mArg1);}
    protected:
        tFunc mFunc; tArg1 mArg1;
    };

    template <class tFunc>
    class TFunction<tFunc, SEmpty,SEmpty,SEmpty,SEmpty,SEmpty,SEmpty,SEmpty>
    {
    public:
        ~TFunction(){}
    public:
        TFunction(tFunc func):mFunc(func){}
    public:
        typename Servise::TFuncTraits<tFunc>::Return_t Execute(){ return (*mFunc)();}
    protected:
        tFunc mFunc; 
    };

    template <class tFunc, class tArg1, class tArg2, class tArg3,class tArg4, class tArg5, class tArg6,class tArg7>
    typename TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,tArg5,tArg6,tArg7>
        TCreate(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3,tArg4 arg4,tArg5 arg5,tArg6 arg6, tArg7 arg7)
    {
        typedef typename TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,tArg5,tArg6,tArg7> My_t;
        return My_t(func, arg1,arg2,arg3,arg4,arg5,arg6,arg7);
    }

    template <class tFunc, class tArg1, class tArg2, class tArg3,class tArg4, class tArg5, class tArg6>
    typename TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,tArg5,tArg6>
        TCreate(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3,tArg4 arg4,tArg5 arg5,tArg6 arg6)
    {
        typedef typename TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,tArg5,tArg6> My_t;
        return My_t(func, arg1,arg2,arg3,arg4,arg5,arg6);
    }

    template <class tFunc, class tArg1, class tArg2, class tArg3,class tArg4, class tArg5>
    typename TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,tArg5>
        TCreate(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3,tArg4 arg4,tArg5 arg5)
    {
        typedef typename TFunction<tFunc, tArg1,tArg2,tArg3,tArg4,tArg5> My_t;
        return My_t(func, arg1,arg2,arg3,arg4,arg5);
    }

    template <class tFunc, class tArg1, class tArg2, class tArg3,class tArg4>
    typename TFunction<tFunc, tArg1,tArg2,tArg3,tArg4>
        TCreate(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3,tArg4 arg4)
    {
        typedef typename TFunction<tFunc, tArg1,tArg2,tArg3,tArg4> My_t;
        return My_t(func, arg1,arg2,arg3,arg4);
    }

    template <class tFunc, class tArg1, class tArg2, class tArg3>
    typename TFunction<tFunc, tArg1,tArg2,tArg3>
        TCreate(tFunc func, tArg1 arg1,tArg2 arg2,tArg3 arg3)
    {
        typedef typename TFunction<tFunc, tArg1,tArg2,tArg3> My_t;
        return My_t(func, arg1,arg2,arg3);
    }

    template <class tFunc, class tArg1, class tArg2>
    typename TFunction<tFunc, tArg1,tArg2>
        TCreate(tFunc func, tArg1 arg1,tArg2 arg2)
    {
        typedef typename TFunction<tFunc, tArg1,tArg2> My_t;
        return My_t(func, arg1,arg2);
    }

    template <class tFunc, class tArg1>
    typename TFunction<tFunc, tArg1>
        TCreate(tFunc func, tArg1 arg1)
    {
        typedef typename TFunction<tFunc, tArg1> My_t;
        return My_t(func, arg1);
    }

    template <class tFunc>
    typename TFunction<tFunc>
        TCreate(tFunc func)
    {
        typedef typename TFunction<tFunc> My_t;
        return My_t(func);
    }



}//Fun


#endif